home *** CD-ROM | disk | FTP | other *** search
- /*
- * This module contains __open() and fstat() from AmiTCP 3.0 beta 2
- * which will be recompiled with our redefined getumask(), geteuid()
- * and getegid() functions from config.h so that we don't need to open
- * usergroup.library if multiuser.library is installed.
- *
- * Author is Jarno Rajahalme <Jarno.Rajahalme@hut.fi>.
- *
- * Copyright © 1993,1994 AmiTCP/IP Group, <amitcp-group@hut.fi>
- * Helsinki University of Technology, Finland.
- * All rights reserved.
- */
-
- #include <stdlib.h>
- #include <string.h>
- #include <stdarg.h>
- #include <errno.h>
- #include <fcntl.h>
- #include <dos.h>
- #include <ios1.h>
- #include <unistd.h>
- #include <sys/types.h>
- #include <sys/stat.h>
- #include <sys/socket.h>
- #include <proto/dos.h>
- #include <proto/utility.h>
- #include <bsdsocket.h>
-
- #include "AmiTCP:src/netlib/netlib.h"
- #include "AmiTCP:src/netlib/fibex.h"
-
- #include "config.h"
-
- int fstat(int fd, struct stat *st)
- {
- struct UFB *ufb = chkufb(fd);
-
- if (st == NULL || ((1 & (long)st) == 1)) {
- errno = EFAULT;
- return -1;
- }
-
- if (ufb == NULL || ufb->ufbflg == 0) {
- errno = EBADF;
- return -1;
- }
-
- if (ufb->ufbflg & UFB_SOCK) { /* a socket */
- long value;
- long size = sizeof(value);
- bzero(st, sizeof(*st));
-
- /* st->st_dev = ??? */
- st->st_mode = S_IFSOCK | S_IRUSR | S_IWUSR;
- st->st_uid = geteuid();
- st->st_gid = getegid();
-
- if (getsockopt(fd, SOL_SOCKET, SO_SNDBUF, &value, &size) == 0)
- st->st_blksize = value;
-
- return 0;
- } else { /* ordinal file */
- if (ExamineFH(ufb->ufbfh, __dostat_fib)) {
- __dostat(__dostat_fib, st);
- st->st_dev = (dev_t)((struct FileHandle *)BADDR(ufb->ufbfh))->fh_Type;
- return 0;
- } else {
- errno = EIO;
- return -1;
- }
- }
- }
-
- extern int (*__closefunc)(int);
-
- __stdargs int
- __open(const char *name, int mode, ...)
- {
- struct UFB *ufb;
- int fd;
- int flags;
- char newfile = TRUE;
- BPTR file;
-
- /*
- * Set up __closefunc (which is used at cleanup)
- */
- __closefunc = __close;
-
- /*
- * Check for the break signals
- */
- __chkabort();
-
- /*
- * find first free ufb
- */
- ufb = __allocufb(&fd);
- if (ufb == NULL)
- return -1; /* errno is set by the __allocufb() */
-
- /*
- * malloc space for the name & copy it
- */
- if ((ufb->ufbfn = malloc(strlen(name)+1)) == NULL) {
- SET_OSERR(ERROR_NO_FREE_STORE);
- errno = ENOMEM;
- return -1;
- }
- strcpy(ufb->ufbfn, name);
- /*
- * Translate mode to ufb flags
- */
- switch (mode & (O_WRONLY | O_RDWR)) {
- case O_RDONLY:
- if (mode & (O_APPEND | O_CREAT | O_TRUNC | O_EXCL)) {
- errno = EINVAL;
- return -1;
- }
- flags = UFB_RA;
- break;
- case O_WRONLY:
- flags = UFB_WA;
- break;
- case O_RDWR:
- flags = UFB_RA | UFB_WA;
- break;
- default:
- errno = EINVAL;
- return -1;
- }
- if (mode & O_APPEND)
- flags |= UFB_APP;
- if (mode & O_XLATE)
- flags |= UFB_XLAT;
- if (mode & O_TEMP)
- flags |= UFB_TEMP;
- if (mode & O_CREAT) {
- BPTR lock;
- if (lock = Lock((char *)name, SHARED_LOCK)) {
- if (mode & O_EXCL) {
- UnLock(lock);
- errno = EEXIST;
- free(ufb->ufbfn);
- return -1;
- }
-
- if (mode & O_TRUNC)
- newfile = FALSE;
- else
- mode &= ~O_CREAT;
-
- UnLock(lock);
- }
- }
- if (mode & O_CREAT) {
- if ((file = Open((char *)name, MODE_NEWFILE)) == NULL)
- goto osfail;
-
- if (newfile) {
- va_list va;
- int cmode;
-
- va_start(va, mode);
-
- cmode = va_arg(va, int) & ~getumask();
-
- chmod((char *)name, cmode); /* hope this doesn't fail :-) */
- }
- }
- else {
- if ((file = Open((char *)name,
- (flags & UFB_WA && mode & O_LOCK) ?
- MODE_READWRITE : MODE_OLDFILE)) == NULL)
- goto osfail;
- }
-
- /*
- * All done! Setting the ufb->ufbflg field to non-zero value marks
- * this ufb used.
- */
- ufb->ufbflg = flags;
- ufb->ufbfh = (long)file;
-
- return fd;
-
- osfail:
- {
- int code = IoErr();
- if (ufb->ufbfn)
- free(ufb->ufbfn);
- set_errno(code);
- }
- return -1;
- }
-